package com.scalar.forecast.forecastEntry.actionCommands;

import com.scalar.forecast.actionCommands.ActionCommand;
import com.scalar.forecast.forecastEntry.forms.ForecastEntryForm;
import com.scalar.forecast.forecastEntry.dao.ForecastEntrySearchDAO;
import com.scalar.forecast.forecastEntry.dao.ForecastEntryDAO;
import com.scalar.forecast.forecastEntry.*;
import com.scalar.forecast.commons.SessionKeys;
import com.scalar.chiptrack.users.User;
import com.scalar.chiptrack.utils.StringUtils;
import com.scalar.chiptrack.db.DBTransaction;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;
import org.apache.struts.action.ActionForm;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.util.*;
import java.text.DecimalFormat;

/**
 * User: Sujan Kumar
 * Date: Feb 21, 2005
 * Time: 9:41:59 PM
 */
public class ForecastEntrySearchBuildViewCommand extends ActionCommand
{
    public ActionForward execute(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response)
    {
        HttpSession session = request.getSession();
        User pUser = ( User )session.getAttribute( SessionKeys.USER_KEY );
        String buildNo = request.getParameter ( "buildNo" );
        ForecastEntryForm forecastEntryForm = new ForecastEntryForm();
        forecastEntryForm.setBuild( true );
        ForecastEntrySearchDAO.loadFormDetailsForBuild ( null, buildNo, forecastEntryForm );
        ArrayList searchFieldList = new ArrayList();
        HashMap errors = new HashMap();
        try
        {
            searchFieldList = ForecastEntrySearchDAO.getForecastSetupSearchFields(null);
            ForecastEntrySalesNewCommand.loadSearchFieldListPropertyValue( forecastEntryForm, searchFieldList );

            int searchFieldListSize = searchFieldList.size();
            SearchField searchField = null;
            //for not to display showNext in the searchfield
            for ( int i=0; i < searchFieldListSize; i++ )
            {
                searchField = ( SearchField )searchFieldList.get( i );
                if ( "showNext".equalsIgnoreCase( searchField.getName() ) )
                {
                    searchField.setDisplay( false );
                    break;
                }
            }
          //  ForecastEntrySearchNewCommand.loadSearchFieldListPropertyValues(forecastEntrySearchForm,searchFieldList);
            //adding new Fields to the search screen

            searchField = new SearchField();
            searchField.setName( "buildNo" );
            searchField.setSortOrder( 9 );
            searchField.setDisplayName ( "Build Number" );
            searchField.setType ( "text" );
            searchField.setDisplay( true );
            searchField.setPropertyName( "buildNo" );
            searchField.setPropertyValue( buildNo );
            searchFieldList.add ( searchField );

            ArrayList entryDetails = ForecastEntrySearchDAO.getEntryDateAndEnteredByForBuildNo( null,buildNo );
            String entryDate = "";
            String enteredBy = "";
            if ( entryDetails != null && entryDetails.size() > 0 )
            {
                entryDate = StringUtils.formatDateToString( ( Date )entryDetails.get ( 0 ) );
                enteredBy = ( String )entryDetails.get ( 1 );
            }
            searchField = new SearchField();
            searchField.setName( "entryDate" );
            searchField.setSortOrder( 10 );
            searchField.setDisplayName ( "Entry Date" );
            searchField.setType ( "text" );
            searchField.setDisplay( true );
            searchField.setPropertyName( "entryDate" );
            searchField.setPropertyValue( entryDate );//todo
            searchFieldList.add ( searchField );

            searchField = new SearchField();
            searchField.setName( "enteredBy" );
            searchField.setSortOrder( 11 );
            searchField.setDisplayName ( "Taken By" );
            searchField.setType ( "text" );
            searchField.setDisplay( true );
            searchField.setPropertyName( "enteredBy" );
            searchField.setPropertyValue( enteredBy );//todo
            searchFieldList.add ( searchField );
        }
        catch ( Exception e )
        {
            errors.put( ERROR_INTERNAL_SERVER_ERROR, ERROR_COULD_NOT_LOAD_SEARCH_FIELDS );
            request.setAttribute( SessionKeys.ERROR_MESSAGES, errors );
            System.out.println ( "----------exception in Getting search fields in sales entry new command ----" );
            e.printStackTrace();
            return mapping.findForward ( "searchBuildPage" );
        }
        Collections.sort( searchFieldList, new SearchFieldListComparator() );
        forecastEntryForm.setSearchFieldList( searchFieldList);
        String userId = pUser.getUserId();
        TableMetaData tableMetaData = ForecastEntrySalesNewCommand.getTableMetaData( forecastEntryForm, userId );
        forecastEntryForm.setTableMetaData( tableMetaData );
        LinkedList rowDataList = null;
        try
        {
            String sPersonId = ( String )session.getAttribute( SessionKeys.USER_SALESPERSON_ID );
            int salesPersonId = -1;
            try
            {
                salesPersonId = Integer.parseInt( sPersonId );
            }
            catch ( NumberFormatException e ){ }
            ArrayList salesPersonIds = new ArrayList();
            salesPersonIds.add ( new Integer ( salesPersonId ) );
            rowDataList = ForecastEntryDAO.getBuildNoRowDataList( null, buildNo );
            setSlotDataList ( forecastEntryForm, rowDataList, buildNo );
            forecastEntryForm.setTableDataList( rowDataList );
            RowData buildRowData = getBuildRowData ( null, forecastEntryForm, buildNo );
            forecastEntryForm.setBuildRowData( buildRowData );
        }
        catch ( Exception e )
        {
            errors.put ( ERROR_INTERNAL_SERVER_ERROR, ERROR_COULD_NOT_LOAD_TABLE_DATA );
            request.setAttribute( SessionKeys.ERROR_MESSAGES, errors );
            System.out.println ( "--Exception while getting the tabledatalist---" );
            e.printStackTrace();
            return mapping.findForward ( "searchPage" );
        }
        /*RowData totalRowData = getTotalRowData ( rowDataList );
        request.setAttribute ( "totalRowData", totalRowData );*/
        request.setAttribute ( "forecastEntryForm", forecastEntryForm );
        return mapping.findForward ( "buildViewPage" );
    }
     public void setSlotDataList ( ForecastEntryForm forecastEntryForm, LinkedList rowDataList, String buildNo )
    {
        int rowDataListSize = rowDataList.size();
        RowData rowData = null;
        LinkedList slotDataList = null;
        SlotData slotData = null;
        for ( int row=0; row < rowDataListSize; row++  )
        {
            rowData = ( RowData ) rowDataList.get ( row );
            slotDataList = new LinkedList();
            int showNext = forecastEntryForm.getShowNext();
            for ( int slot=0; slot < showNext; slot++ )
            {
                slotData = new SlotData();
                try
                {
                    slotData = ForecastEntryDAO.getBuilNoSlotData (null, slot, forecastEntryForm, rowData.getSalesPersonId(), buildNo );
                }
                catch ( Exception e )
                {
                    System.out.println ( "--Exception while getting the slotData---" );
                    e.printStackTrace();
                }
                slotDataList.addLast( slotData );
            }
            rowData.setSlotDataList( slotDataList );
        }
    }

    /**
     * This method calculates the total Qty and Average Price for each slot for the rowDataList passed.
     * And returns this info as the rowData object.
     * @param rowDataList
     * @return
     */
    private RowData getTotalRowData ( LinkedList rowDataList )
    {
        SlotData totalSlotData = null, slotData = null;
        RowData totalRowData = new RowData();
        RowData rowData = null;
        LinkedList totalSlotDataList = new LinkedList();
        LinkedList slotDataList = null;
        int rowDataListSize = rowDataList.size();
        for ( int row = 0; row < rowDataListSize; row++ )
        {
            rowData = ( RowData )rowDataList.get ( row );
            slotDataList = rowData.getSlotDataList();
            int slotDataListSize = slotDataList.size();
            if ( row == 0 )
            {
                for ( int slot=0; slot < slotDataListSize; slot++ )
                {
                    totalSlotDataList.addLast( new SlotData() );
                }
            }

            for ( int slot=0; slot < slotDataListSize; slot++ )
            {
                totalSlotData = ( SlotData )totalSlotDataList.get ( slot );
                slotData = ( SlotData ) slotDataList.get ( slot );
                totalSlotData.setQty( totalSlotData.getQty() + slotData.getQty() );
                double avgPrice = 0.0d;
                if ( row == 0 )
                {
                    avgPrice = slotData.getPrice();
                    totalSlotData.setPrice ( avgPrice );
                }
                else
                {
                    avgPrice = ( ( totalSlotData.getPrice() * row ) + slotData.getPrice() ) / (row+1) ;
                    //avgPrice = Math.round(avgPrice*100)/100; //cutting down to 2 decimal places..
                    DecimalFormat decimalFormat = new DecimalFormat( "############.00" );
                    totalSlotData.setPrice( Double.parseDouble ( decimalFormat.format( avgPrice ) ) );
                }
            }
        }
        totalRowData.setSlotDataList( totalSlotDataList );
        return totalRowData;
    }
    private RowData getBuildRowData ( DBTransaction dbTransaction,ForecastEntryForm forecastEntryForm, String buildNo )
    {
        RowData buildRowData = new RowData();
        LinkedList slotDataList = new LinkedList();
        SlotData slotData = null;
        int showNext = forecastEntryForm.getShowNext();
        for ( int slot=0; slot < showNext; slot++ )
        {
            slotData = new SlotData();
            try
            {
                slotData = ForecastEntryDAO.getBuilNoSlotData ( dbTransaction, slot, forecastEntryForm, 0, buildNo );
            }
            catch ( Exception e )
            {
                System.out.println ( "--Exception while getting the Build Row slotData---" );
                e.printStackTrace();
            }
            slotDataList.addLast( slotData );
        }
        buildRowData.setSlotDataList( slotDataList );
        return buildRowData;
    }
}
